package product

import (
	"errors"
	"go-ddd-ecommerce/internal/domain/events"

	"github.com/google/uuid"
)

// Product 商品实体 - 充血模型
type Product struct {
	ID     uuid.UUID
	Name   string
	Price  float64
	Stock  int
	events []events.DomainEvent // 记录领域事件,临时存储待发布的事件
}

// NewProduct 创建一个商品
func NewProduct(name string, price float64, stock int) (*Product, error) {
	if name == "" {
		return nil, errors.New("商品名不能为空")
	}
	if price <= 0 {
		return nil, errors.New("商品价格必须大于0")
	}
	if stock < 0 {
		return nil, errors.New("商品库存必须大于0")
	}
	product := &Product{
		ID:     uuid.New(),
		Name:   name,
		Price:  price,
		Stock:  stock,
		events: make([]events.DomainEvent, 0),
	}
	// 发布新增用户事件
	product.events = append(product.events, events.NewProductCreatedEvent(product.ID, product.Name, product.Price, product.Stock))
	return product, nil
}

// 更新库存
func (p *Product) UpdateStock(newStock int) error {
	if newStock < 0 {
		return errors.New("商品库存必须大于0")
	}
	p.Stock = newStock
	// 发布更新库存事件
	p.events = append(p.events, events.NewProductStockUpdateEvent(p.ID, newStock, p.Stock))
	return nil
}

// 扣除库存
func (p *Product) DeductStock(quantity int) error {
	if quantity <= 0 {
		return errors.New("商品数量必须大于0")
	}
	if p.Stock < quantity {
		return errors.New("库存不足")
	}
	p.Stock -= quantity

	// 发布库存减少事件
	p.events = append(p.events, events.NewProductStockUpdateEvent(p.ID, -quantity, p.Stock))
	return nil
}

// 增加库存
func (p *Product) AddStock(quantity int) error {
	if quantity <= 0 {
		return errors.New("商品数量必须大于0")
	}
	p.Stock += quantity
	// 发布库存增加事件
	p.events = append(p.events, events.NewProductStockUpdateEvent(p.ID, quantity, p.Stock))
	return nil
}

// 更新价格
func (p *Product) UpdatePrice(newPrice float64) error {
	if newPrice <= 0 {
		return errors.New("商品价格必须大于0")
	}
	oldPrice := p.Price
	p.Price = newPrice
	// 发布价格更新事件
	p.events = append(p.events, events.NewProductUpdatePriceEvent(p.ID, oldPrice, newPrice))
	return nil
}

// GetDomainEvents 获取待发布的事件
// 实现事件生产器的接口
func (p *Product) GetDomainEvents() []events.DomainEvent {
	return p.events
}

// ClearDomainEvents 清空已发布的事件
// 实现事件生产器的接口
func (p *Product) ClearDomainEvents() {
	p.events = make([]events.DomainEvent, 0)
}
